<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
use App\Repositories\GamerRepository;
use App\Repositories\GameServer\RechargeRecordRepository;
use App\Repositories\GameServer\PlayRecordRepository;
use App\Repositories\GameServer\LoginRecordRepository;
// use Hisune\EchartsPHP\ECharts;

/**
 * 代码冗余非常厉害，抱歉,--外观模式可优化代码
 */
class IndexController extends Controller
{
    public $date_type = [
        'time' => [
            '0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23'
        ],
        'range_time' => [
            '0','2','4','6','8','10','12','14','16','18','20','22'
        ]
    ];

    protected $channels = [
        '官方渠道','IOS','应用宝'
    ];
    protected $PlayRecord;

	public function __construct(PlayRecordRepository $playRecord)
	{
		$this->middleware('admin.auth');
        $this->PlayRecord = $playRecord;
	}


    public function index(Request $request)
    {
        $where['start'] = Carbon::now()->startOfDay()->timestamp;
        $where['end'] = Carbon::now()->endOfDay()->timestamp;
        $where['format'] = '%k';

        $gamer_num = GamerRepository::getGamerNum();//用户总数
        // $month_active_num = LoginRecordRepository::getMonthActiveNum();//MAU月活跃用户数量
        $recharge_gamer_num = RechargeRecordRepository::getRechargeGamerNum();//累计付费用户
        $recharge_rate = RechargeRecordRepository::getRechargeRate();//付费率
        $active_gamer_num = PlayRecordRepository::getActiveGamerNum();//有效用户数
        $arpu = RechargeRecordRepository::getArpu();//ARPU=当月活跃用户充值总额/当月付费用户数量
        // $avg_online_time = LoginRecordRepository::getAvgOnlineTime();//当日用户平均在线时长
        $recharge_amount = RechargeRecordRepository::getSumRechargeAmount();//累计付费金额
        $ltv30 = RechargeRecordRepository::getLTV();//30日LTV
        $arppu = RechargeRecordRepository::getArppu();//ARPPU

        $channels = $this->getChannelGamers($where);//渠道统计

        //默认新增用户
        $chart = json_encode($this->getNewRegGamers($request));
        // dd($this->getActiveGamers($request));



    	return view('admin.index', compact('gamer_num','month_active_num','recharge_gamer_num','recharge_rate','active_gamer_num','arpu','avg_online_time','recharge_amount','ltv30','arppu','chart','channels'));

    }

    /**
     * 获取指定日期段内每一天的日期
     * @param  Date  $startdate 开始日期
     * @param  Date  $enddate   结束日期
     * @return Array
     */
    function getDateFromRange($startdate, $enddate, $format)
    {
        // $format = '%Y-%m-%d';
        $format = str_replace('%', '', $format);
        if ($format == 'k') $format = 'G';

        while ($startdate->timestamp <= $enddate->timestamp) {
            $key = date($format, $startdate->timestamp);
            $xAxis[] = date($format, $startdate->timestamp);
            $date[$key] = 0;

            if ($format == 'Y-m-d') {
                $startdate->addDay();
            }
            elseif ($format == 'Y-m') {
                $startdate->addMonth();
            }
            else {
                $startdate->addHour();
            }
        }

        $res = [$date, $xAxis];
        return $res;
    }

    //图表
    public function getChart($xAxis, $series, $title = '')
    {
        $chart = new ECharts();

        $chart->title->text = $title;
        $chart->tooltip->show = true;
        $chart->tooltip->trigger = 'axis';
        $chart->legend->data[] = $title;
        $chart->toolbox->right = '2%';
        $chart->toolbox->feature->saveAsImage = [];

        $chart->grid[] = [
            'left' => '3%',
            'right' => '4%',
            'bottom' => '15%',
            'containLabel' => true
        ];

        $chart->dataZoom = [[
            'type' => 'slider',
            'show' => true,
            'xAxisIndex' => 0,
            'filterMode' => 'filter',
            'start' => 0,
            'end' => 100,
            'handleSize' => '50%',
            'bottom' => '5%',
        ],[
            'type' => 'inside',
            'start' => 50,
            'end' => 100,
        ]];

        $chart->xAxis[] = array(
            'type' => 'category',
            'boundaryGap' => true,
            'data' => $xAxis
        );

        $chart->yAxis[] = array(
            'type' => 'value'
        );

        $chart->series[] = array(
            'name' => $title,
            'type' => 'line',
            'data' => $series
        );

        $polyline = $chart->render('chart', array('style' => 'width:100%;height:400px;'));

        return $polyline;
    }

    //异步获取数据
    public function getChartData(Request $request)
    {
        if ($request->date) {
            $date = explode('~', $request->date);
            $start = Carbon::parse($date[0]);
            $end = Carbon::parse($date[1]);
        } else {
            $start = Carbon::now()->startOfDay();
            $end = Carbon::now()->endOfDay();

        }

        if ($request->kind == 'day') { //按日
            $format = '%Y-%m-%d';
        }
        elseif ($request->kind == 'month') {//按月
            $format = '%Y-%m';
        }
        else {//按小时
            $format = '%k';
        }

        $where['start'] = $start->timestamp;
        $where['end'] = $end->timestamp;
        $where['format'] = $format;

        $data = [];
        $arr = $this->getDateFromRange($start, $end, $format);//x轴初始化

        $channels_summary = $this->getChannelGamers($where);//渠道用户汇总

        $type = $request->type;

        switch ($type) {
            case 'add':
                $data = $this->getNewRegGamers($request);
                break;
            case 'active':
                $data = $this->getActiveGamers($request);
                break;
            case 'valid_active':
                $data = $this->getValidActiveGamers($request);
                break;
            case 'sum':
                $data = $this->getPlayRecordAmount($request);
                break;
            case 'average':
                $data = $this->getGameAverage($request);
                break;
            case 'median':
                $data = $this->getActiveGamers($request);
                break;
            case 'arpu':
                $data = $this->getArpu($request);
                break;
            case 'arppu':
                $data = $this->getActiveGamers($request);
                break;
            default:
                return json_encode(['status' => 1, 'msg' => '操作失败']);
                break;
        }

        $res = [
            'status' => 0,
            'chart' => $data,
            'channels_summary' => $channels_summary
        ];

        return json_encode($res);

    }

    //渠道用户分类统计
    public function getChannelGamers($where)
    {
        $channels = $this->channels;
        $gamer_ids = PlayRecordRepository::getGamerIds($where)->pluck('account_id');
        $where['ids'] = $gamer_ids;

        //有效用户--渠道
        $valid_active_channel = GamerRepository::getValidActiveGamerNum($where)->pluck('count', 'distributer_id');
        unset($where['ids']);

        $sum_channel = PlayRecordRepository::getPlayRecordNumOfChannel($where)->pluck('count', 'distributer_id');//玩牌局数
        $avg_channel = PlayRecordRepository::getPlayRecordAvgOfChannel($where)->pluck('avg', 'distributer_id');//玩牌平均数

        $res = [];
        foreach ($channels as $key => $val) {
            $where['channel'] = $key;

            $data = [];
            $data['name'] = $val;
            $data['new'] = GamerRepository::getNewGamerNum($where);//新增
            // $data['active'] = LoginRecordRepository::getActiveGamers($where)->count();//活跃
            $data['active'] = GamerRepository::getActiveGamerNum($where);//活跃
            $data['valid_active'] = isset($valid_active_channel[$key]) ? $valid_active_channel[$key] : 0;//有效活跃
            $data['sum'] = $sum_channel[$key] ?? 0;//玩牌局数
            $data['average'] = $avg_channel[$key] ?? 0;//玩牌平均数


            $res[] = $data;
        }

        return $res;

    }

    //获取新增用户
    public function getNewRegGamers(Request $request)
    {
        if ($request->date) {
            $date = explode('~', $request->date);
            $start = Carbon::parse($date[0]);
            $end = Carbon::parse($date[1]);
        } else {
            $start = Carbon::now()->startOfDay();
            $end = Carbon::now()->endOfDay();

        }

        if ($request->kind == 'day') { //按日
            $format = '%Y-%m-%d';
        }
        elseif ($request->kind == 'month') {//按月
            $format = '%Y-%m';
        }
        else {//按小时
            $format = '%k';
        }

        $where['start'] = $start->timestamp;
        $where['end'] = $end->timestamp;
        $where['format'] = $format;

        $data = [];
        $arr = $this->getDateFromRange($start, $end, $format);//x轴默认值,初始化
        $gamers = GamerRepository::getRegGamerBytime($where);
        // dd($arr);

        foreach ($gamers as $key => $val) {
            $data[$val->time] = $val->num;
        }

        $data = array_replace($arr[0], $data);
        $series = array_values($data);

        $res = [
            'title' => '新增用户',
            'legend' => ['新增用户'],
            'xAxis' => $arr[1],
            'series' => [['name' => '新增用户', 'type' => 'line', 'data' => $series]]
        ];

        return $res;
    }


    //获取活跃用户 == 有一次登录
    public function getActiveGamers(Request $request)
    {
        if ($request->date) {
            $date = explode('~', $request->date);
            $start = Carbon::parse($date[0]);
            $end = Carbon::parse($date[1]);
        } else {
            $start = Carbon::now()->startOfDay();
            $end = Carbon::now()->endOfDay();

        }

        if ($request->kind == 'day') { //按日
            $format = '%Y-%m-%d';
        }
        elseif ($request->kind == 'month') {//按月
            $format = '%Y-%m';
        }
        else {//按小时
            $format = '%k';
        }

        $where['start'] = $start->timestamp;
        $where['end'] = $end->timestamp;
        $where['format'] = $format;

        $data = [];
        $arr = $this->getDateFromRange($start, $end, $format);//x轴初始化

        $gamers = LoginRecordRepository::getActiveGamers($where);

        foreach ($gamers as $key => $val) {
            $data[$val->time] = $val->num;
        }

        $data = array_replace($arr[0], $data);
        $series = array_values($data);

        $res = [
            'title' => '活跃用户',
            'legend' => ['活跃用户'],
            'xAxis' => $arr[1],
            'series' => ['name' => '活跃用户', 'type' => 'line', 'data' => $series]
        ];

        return $res;
    }

    //获取有效活跃用户
    public function getValidActiveGamers111(Request $request)
    {
        $start = isset($request->start) ? Carbon::parse($request->start) : Carbon::now()->startOfDay();
        $end = isset($request->end) ? Carbon::parse($request->end) : Carbon::now()->endOfDay();
        $where['start'] = $start->timestamp;
        $where['end'] = $end->timestamp;

        $gamers = PlayRecordRepository::getValidActiveGamers($where);

        $data = [];
        $arr = array_fill(0, 24, 0);

        foreach ($gamers as $key => $val) {
            $data[(int)$val->time] = $val->num;
        }

        $series = array_replace($arr, $data);

        $res = [
            'title' => '有效活跃用户',
            'legend' => ['有效活跃用户'],
            'xAxis' => $this->date_type['time'],
            'series' => ['name' => '有效活跃用户', 'type' => 'line', 'data' => $series]
        ];

        return $res;
    }

    public function getValidActiveGamers(Request $request)
    {
        if ($request->date) {
            $date = explode('~', $request->date);
            $start = Carbon::parse($date[0]);
            $end = Carbon::parse($date[1]);
        } else {
            $start = Carbon::now()->startOfDay();
            $end = Carbon::now()->endOfDay();

        }

        if ($request->kind == 'day') { //按日
            $format = '%Y-%m-%d';
        }
        elseif ($request->kind == 'month') {//按月
            $format = '%Y-%m';
        }
        else {//按小时
            $format = '%k';
        }

        $where['start'] = $start->timestamp;
        $where['end'] = $end->timestamp;
        $where['format'] = $format;

        $data = [];
        $arr = $this->getDateFromRange($start, $end, $format);//x轴初始化
        $gamers = PlayRecordRepository::getValidActiveGamers($where);

        foreach ($gamers as $key => $val) {
            $data[$val->time] = $val->num;
        }

        $data = array_replace($arr[0], $data);
        $series = array_values($data);

        $res = [
            'title' => '有效活跃用户',
            'legend' => ['有效活跃用户'],
            'xAxis' =>  $arr[1],
            'series' => ['name' => '有效活跃用户', 'type' => 'line', 'data' => $series]
        ];

        return $res;
    }

    //玩牌局数
    public function getPlayRecordAmount(Request $request)
    {
        if ($request->date) {
            $date = explode('~', $request->date);
            $start = Carbon::parse($date[0]);
            $end = Carbon::parse($date[1]);
        } else {
            $start = Carbon::now()->startOfDay();
            $end = Carbon::now()->endOfDay();

        }

        if ($request->kind == 'day') { //按日
            $format = '%Y-%m-%d';
        }
        elseif ($request->kind == 'month') {//按月
            $format = '%Y-%m';
        }
        else {//按小时
            $format = '%k';
        }

        $where['start'] = $start->timestamp;
        $where['end'] = $end->timestamp;
        $where['format'] = $format;

        $data = [];
        $arr = $this->getDateFromRange($start, $end, $format);//x轴初始化
        $gamers = PlayRecordRepository::getPlayRecordNum($where);

        foreach ($gamers as $key => $val) {
            $data[$val->time] = $val->num;
        }

        $data = array_replace($arr[0], $data);
        $series = array_values($data);

        $res = [
            'title' => '当日玩牌局数',
            'legend' => ['当日玩牌局数'],
            'xAxis' => $arr[1],
            'series' => ['name' => '当日玩牌局数', 'type' => 'line', 'data' => $series]
        ];

        return $res;
    }

    //玩牌平均数
    public function getGameAverage(Request $request)
    {
        if ($request->date) {
            $date = explode('~', $request->date);
            $start = Carbon::parse($date[0]);
            $end = Carbon::parse($date[1]);
        } else {
            $start = Carbon::now()->startOfDay();
            $end = Carbon::now()->endOfDay();

        }

        if ($request->kind == 'day') { //按日
            $format = '%Y-%m-%d';
        }
        elseif ($request->kind == 'month') {//按月
            $format = '%Y-%m';
        }
        else {//按小时
            $format = '%k';
        }

        $where['start'] = $start->timestamp;
        $where['end'] = $end->timestamp;
        $where['format'] = $format;

        $data = [];
        $arr = $this->getDateFromRange($start, $end, $format);//x轴初始化
        $gamers = PlayRecordRepository::getPlayRecordAvg($where);

        foreach ($gamers as $key => $val) {
            $data[$val->time] = $val->num;
        }

        $data = array_replace($arr[0], $data);
        $series = array_values($data);

        $res = [
            'title' => '当日玩牌平均数',
            'legend' => ['当日玩牌平均数'],
            'xAxis' => $arr[1],
            'series' => ['name' => '当日玩牌平均数', 'type' => 'line', 'data' => $series]
        ];

        return $res;
    }

    //获取ARPU
    public function getArpu(Request $request)
    {
        if ($request->date) {
            $date = explode('~', $request->date);
            $start = Carbon::parse($date[0]);
            $end = Carbon::parse($date[1]);
        } else {
            $start = Carbon::now()->startOfDay();
            $end = Carbon::now()->endOfDay();

        }

        if ($request->kind == 'day') { //按日
            $format = '%Y-%m-%d';
        }
        elseif ($request->kind == 'month') {//按月
            $format = '%Y-%m';
        }
        else {//按小时
            $format = '%k';
        }

        $where['start'] = $start->timestamp;
        $where['end'] = $end->timestamp;
        $where['format'] = $format;

        $data = [];
        $arr = $this->getDateFromRange($start, $end, $format);//x轴初始化
        $gamers = PlayRecordRepository::getPlayRecordAvg($where);

        foreach ($gamers as $key => $val) {
            $data[$val->time] = $val->num;
        }

        $data = array_replace($arr[0], $data);
        $series = array_values($data);

        $res = [
            'title' => 'ARPU',
            'legend' => ['ARPU'],
            'xAxis' => $arr[1],
            'series' => ['name' => 'ARPU', 'type' => 'line', 'data' => $series]
        ];

        return $res;
    }
}
